package info.nixbear.tgcms.admin.client.view;

import info.nixbear.tgcms.admin.client.view.cell.CustomSelectionCell;
import info.nixbear.tgcms.admin.shared.request.AttachmentProxy;
import info.nixbear.tgcms.admin.shared.request.PageProxy;
import info.nixbear.tgcms.admin.shared.request.PageRequest;
import info.nixbear.tgcms.admin.shared.request.StringTextKvpProxy;
import info.nixbear.tgcms.admin.shared.request.TemplateProxy;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.google.gwt.cell.client.ActionCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.ImageCell;
import com.google.gwt.cell.client.TextInputCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.adapters.HasDataEditor;
import com.google.gwt.editor.client.adapters.TakesValueEditor;
import com.google.gwt.editor.ui.client.ValueBoxEditorDecorator;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.text.shared.Renderer;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.IdentityColumn;
import com.google.gwt.user.client.TakesValue;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.RichTextArea;
import com.google.gwt.user.client.ui.ValueListBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.ProvidesKey;

public class PageEditor extends Composite implements Editor<PageProxy> {

	private static PageEditorUiBinder uiBinder = GWT.create(PageEditorUiBinder.class);

	interface PageEditorUiBinder extends UiBinder<Widget, PageEditor> {
	}

	@UiField(provided = true)
	CellTable<StringTextKvpProxy> attributesTable;

	HasDataEditor<StringTextKvpProxy> attributesListEditor;

	ListDataProvider<StringTextKvpProxy> attributesDataProvider = new ListDataProvider<StringTextKvpProxy>();

	@UiField(provided = true)
	CellTable<AttachmentProxy> attachmentsTable;

	HasDataEditor<AttachmentProxy> attachmentsEditor;

	public ListDataProvider<AttachmentProxy> attachmentsDataProvider = new ListDataProvider<AttachmentProxy>();

	Collection<TemplateProxy> templates = new ArrayList<TemplateProxy>();
	Column<AttachmentProxy, String> templateColumn;
	
	public PageEditor() {

		attributesTable = new CellTable<StringTextKvpProxy>(new ProvidesKey<StringTextKvpProxy>() {
			public Object getKey(StringTextKvpProxy item) {
				return item == null ? null : item.getId();
			}
		});

		attributesTable.setWidth("100%", true);
		attributesTable.setPageSize(30);

		Column<StringTextKvpProxy, String> keyColumn = new Column<StringTextKvpProxy, String>(
				new TextInputCell()) {

			@Override
			public String getValue(StringTextKvpProxy object) {
				return object.getKey();
			}
		};
		keyColumn.setFieldUpdater(new FieldUpdater<StringTextKvpProxy, String>() {
			public void update(int index, StringTextKvpProxy object, String value) {
				object.setKey(value);
			}
		});
		attributesTable.addColumn(keyColumn, "Key");

		Column<StringTextKvpProxy, String> valueColumn = new Column<StringTextKvpProxy, String>(
				new TextInputCell()) {

			@Override
			public String getValue(StringTextKvpProxy object) {
				return object.getValueAsString();
			}
		};
		valueColumn.setFieldUpdater(new FieldUpdater<StringTextKvpProxy, String>() {
			public void update(int index, StringTextKvpProxy object, String value) {
				object.setValueAsString(value);
			}
		});
		attributesTable.addColumn(valueColumn, "Value");

		Column<StringTextKvpProxy, StringTextKvpProxy> deleteColumn = new IdentityColumn<StringTextKvpProxy>(
				new ActionCell<StringTextKvpProxy>("delete",
						new ActionCell.Delegate<StringTextKvpProxy>() {
							public void execute(StringTextKvpProxy object) {
								attributesListEditor.getList().remove(object);
							}
						}));
		attributesTable.addColumn(deleteColumn, "");

		attributesDataProvider.addDataDisplay(attributesTable);

		// pager.setDisplay(attributesTable);

		attributesListEditor = HasDataEditor.of(attributesTable);

		attachmentsTable = new CellTable<AttachmentProxy>();
//		new ProvidesKey<AttachmentProxy>() {
//			public Object getKey(AttachmentProxy item) {
//				return item == null ? null : item.getId();
//			}
//		});

		attachmentsTable.setWidth("100%", true);
		attachmentsTable.setPageSize(30);

		Column<AttachmentProxy, String> previewColumn = new Column<AttachmentProxy, String>(
				new ImageCell()) {
			@Override
			public String getValue(AttachmentProxy object) {
				String url = object.getServingUrl();
				return url;
			}
		};
		attachmentsTable.addColumn(previewColumn, "Preview");

		Column<AttachmentProxy, String> titleColumn = new Column<AttachmentProxy, String>(
				new TextInputCell()) {

			@Override
			public String getValue(AttachmentProxy object) {
				return object.getTitle();
			}
		};
		titleColumn.setFieldUpdater(new FieldUpdater<AttachmentProxy, String>() {
			public void update(int index, AttachmentProxy object, String value) {
				object.setTitle(value);
			}
		});
		attachmentsTable.addColumn(titleColumn, "Title");

		Column<AttachmentProxy, String> contentColumn = new Column<AttachmentProxy, String>(
				new TextInputCell()) {

			@Override
			public String getValue(AttachmentProxy object) {
				return object.getContentAsString();
			}
		};
		contentColumn.setFieldUpdater(new FieldUpdater<AttachmentProxy, String>() {
			public void update(int index, AttachmentProxy object, String value) {
				object.setContentAsString(value);
			}
		});
		attachmentsTable.addColumn(contentColumn, "Description");

		templateColumn = new Column<AttachmentProxy, String>(
				new CustomSelectionCell(new ArrayList<String>())) {
			@Override
			public String getValue(AttachmentProxy object) {
				return (object.getTemplate() != null)?object.getTemplate().getName():"";
			}
		};

		templateColumn.setFieldUpdater(new FieldUpdater<AttachmentProxy, String>() {
			public void update(int index, AttachmentProxy object, String value) {
				for(TemplateProxy template : templates) {
					if(template.getName().equals(value)) {
						object.setTemplate(template);
						break;
					}
				}
			}
		});
		attachmentsTable.addColumn(templateColumn, "Template");
		
		Column<AttachmentProxy, String> urlColumn = new Column<AttachmentProxy, String>(
				new TextInputCell()) {

			@Override
			public String getValue(AttachmentProxy object) {
				return object.getUrl();
			}
		};
		urlColumn.setFieldUpdater(new FieldUpdater<AttachmentProxy, String>() {
			public void update(int index, AttachmentProxy object, String value) {
				object.setUrl(value);
			}
		});
		attachmentsTable.addColumn(urlColumn, "Url");

		Column<AttachmentProxy, AttachmentProxy> deleteFileColumn = new IdentityColumn<AttachmentProxy>(
				new ActionCell<AttachmentProxy>("delete",
						new ActionCell.Delegate<AttachmentProxy>() {
							public void execute(AttachmentProxy object) {
								attachmentsDataProvider.getList().remove(object);
							}
						}));
		attachmentsTable.addColumn(deleteFileColumn, "");

		attachmentsDataProvider.addDataDisplay(attachmentsTable);

		attachmentsEditor = HasDataEditor.of(attachmentsTable);

		contentAsStringTA = new RichTextAreaEnhanced();
		contentAsStringToolbar = new RichTextToolbar(contentAsStringTA);
		contentAsStringTA.setRichTextToolbar(contentAsStringToolbar);
		contentAsStringTA.setWidth("100%");
		contentAsStringTA.setHeight("300px");

		contentAsStringEditor = TakesValueEditor.of(contentAsStringTA);

		initWidget(uiBinder.createAndBindUi(this));

	}

	public void updateAttributesTable() {
		attributesDataProvider
				.setList((attributesListEditor.getList() == null) ? new ArrayList<StringTextKvpProxy>()
						: attributesListEditor.getList());
	}

	public void updateAttachmentsTable() {
		attachmentsDataProvider
				.setList((attachmentsEditor.getList() == null) ? new ArrayList<AttachmentProxy>()
						: attachmentsEditor.getList());
	}

	@UiField
	Button addAttribute;

	@UiHandler(value = { "addAttribute" })
	void onAddAttribute(ClickEvent event) {
		StringTextKvpProxy newAttribute = request.create(StringTextKvpProxy.class);
		attributesDataProvider.getList().add(newAttribute);
	}

	@UiField
	ValueBoxEditorDecorator<String> title;

	@UiField
	ValueBoxEditorDecorator<String> url;

	@UiField(provided = true)
	RichTextAreaEnhanced contentAsStringTA;

	@UiField(provided = true)
	RichTextToolbar contentAsStringToolbar;

	TakesValueEditor<String> contentAsStringEditor;

	public static class RichTextAreaEnhanced extends RichTextArea implements TakesValue<String> {

		RichTextToolbar richTextToolbar;

		@Override
		public void setValue(String value) {
			if (this.richTextToolbar.isHTMLMode()) {
				this.setText(value);
			} else {
				this.setHTML(value);

			}
		}

		@Override
		public String getValue() {
			if (this.richTextToolbar.isHTMLMode()) {
				return this.getText();
			} else {
				return this.getHTML();
			}
		}

		public void setRichTextToolbar(RichTextToolbar richTextToolbar) {
			this.richTextToolbar = richTextToolbar;
		}
	}

	@UiField(provided = true)
	ValueListBox<TemplateProxy> template = new ValueListBox<TemplateProxy>(
			new Renderer<TemplateProxy>() {
				@Override
				public String render(TemplateProxy key) {
					return (key == null) ? null : key.getName();
				}

				@Override
				public void render(TemplateProxy object, Appendable appendable) throws IOException {
					appendable.append(this.render(object));
				}
			});

	public void setTemplates(Collection<TemplateProxy> newValues) {
		this.template.setAcceptableValues(newValues);
		List<String> options = new ArrayList<String>();
		for(TemplateProxy t : newValues) {
			options.add(t.getName());
		}
		((CustomSelectionCell) this.templateColumn.getCell()).updateOptions(options);
		this.templates = newValues;
	}

	PageProxy page;
	public PageRequest request;

	public void edit(PageProxy page, PageRequest request) {
		this.page = page;
		this.request = request;
	}

	public void stop() {
		attributesDataProvider.setList(new ArrayList<StringTextKvpProxy>());
		attachmentsDataProvider.setList(new ArrayList<AttachmentProxy>());
	}

}
